<template>
  <div class="calendar">
    <div class="weekdays weeks">
      <div v-for="day in weekdays" :key="day" class="week-item">
        <div class="cn">{{ day.cn }}</div>
        <div class="en">{{ day.en }}</div>
      </div>
    </div>
    <div class="weeks">
      <div v-for="(week, weekIndex) in weeksInMonth" :key="weekIndex" class="week">
        <div
          v-for="(day, dayIndex) in week"
          :key="dayIndex"
          class="day-item"
          :class="{
            'not-current': day === 0,
            'special-day': isSpecialDay(day),
            'selected-day': isSelectedDay(day),
            disabled: !canSelectDay(day, dayIndex)
          }"
          @click="selectDay(day, dayIndex)"
        >
          {{ day || '' }}
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, defineProps, defineEmits, onMounted, watch } from 'vue'

const props = defineProps({
  config: {
    type: Object as () => {
      displayMonth: string
      specialDays: Array<{ start: number; end: number }>
    },
    default: () => ({
      displayMonth: `${new Date().getFullYear()}-${new Date().getMonth() + 1}`,
      specialDays: []
    })
  },
  selectedDate: String
})

const emit = defineEmits(['update:selectedDate'])

const weekdays = ref([
  { cn: '周日', en: 'Sun' },
  { cn: '周一', en: 'Mon' },
  { cn: '周二', en: 'Tue' },
  { cn: '周三', en: 'Wed' },
  { cn: '周四', en: 'Thu' },
  { cn: '周五', en: 'Fri' },
  { cn: '周六', en: 'Sat' }
])

const year = ref('')
const month = ref('')

// 获取当前显示的月份
const displayMonth = computed(() => props.config.displayMonth)
// 获取特殊日期范围数组
const specialDays = computed(() => props.config.specialDays || [])

// 格式化显示月份（如：2025年7月）
const formattedDisplayMonth = computed(() => {
  return `${year.value}年${parseInt(month.value) + 1}月`
})

// 获取当月天数
const daysInMonth = computed(() => {
  const date = new Date(parseInt(year.value, 10), parseInt(month.value, 10) + 1, 0)
  return Array.from({ length: date.getDate() }, (_, i) => i + 1)
})

// 获取第一天是星期几
const firstDayOfMonth = computed(() => {
  const date = new Date(parseInt(year.value, 10), parseInt(month.value, 10), 1)
  return date.getDay()
})

// 计算每周的结构
const weeksInMonth = computed(() => {
  const days = daysInMonth.value
  const firstDay = firstDayOfMonth.value
  const weeks = []
  let week = []

  for (let i = 0; i < firstDay; i++) {
    week.push(0)
  }

  days.forEach((day) => {
    week.push(day)
    if (week.length === 7) {
      weeks.push(week)
      week = []
    }
  })

  if (week.length > 0) {
    while (week.length < 7) {
      week.push(0)
    }
    weeks.push(week)
  }

  return weeks
})

// 判断是否是特殊日期范围内
const isSpecialDay = (day: number) => {
  if (!specialDays.value || specialDays.value.length === 0) return false

  for (const range of specialDays.value) {
    const { start, end } = range
    if (day >= start && day <= end) {
      return true
    }
  }

  return false
}
// 添加是否是选中的日期
const isSelectedDay = (day: number) => {
  if (!props.selectedDate) return false

  const [getFullYear, getMonth, getDay] = props.selectedDate.split('-').map(Number)
  const currentYear = parseInt(year.value)
  const currentMonth = parseInt(month.value)

  return day === getDay && getFullYear === currentYear && getMonth - 1 === currentMonth
}
// 判断是否允许选择该日期
const canSelectDay = (day: number, dayIndex: number) => {
  if (day === 0) return false // 非本月不可选

  const date = new Date(parseInt(year.value), parseInt(month.value), day)
  const dayOfWeek = date.getDay()

  // 周一禁止选择
  if (dayOfWeek === 1) return false

  // 其他日期只允许 specialDays 可选
  return isSpecialDay(day)
}

// 选择日期事件
const selectDay = (day: number, dayIndex: number) => {
  if (canSelectDay(day, dayIndex)) {
    emit(
      'update:selectedDate',
      `${year.value}-${parseInt(month.value) >= 9 ? parseInt(month.value) + 1 : '0' + (parseInt(month.value) + 1)}-${
        day >= 9 ? day : '0' + day
      }`
    )
  }
}

// 初始化年、月数据
const initDate = () => {
  const [getFullYear, getMonth] = displayMonth.value.split('-').map(Number)
  year.value = getFullYear.toString()
  month.value = (getMonth - 1).toString()

  // 如果没有选中日期，则清空
  if (!props.selectedDate) {
    emit('update:selectedDate', '')
  }
}

// 监听 config 变化并刷新日历
watch(
  () => props.config,
  () => {
    console.log('监听 config 改变')
    initDate()
  },
  { deep: true }
)

onMounted(() => {
  initDate()
})
</script>

<style scoped lang="scss">
.calendar {
  width: 670rpx;
  margin: 0 auto;
  text-align: center;
  padding-bottom: 10rpx;
}

.weekdays,
.weeks {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}

.weekdays {
  margin-bottom: 30rpx;
  .week-item {
    width: 64rpx;
    margin-right: 34rpx;
    text-align: left;
    &:last-child {
      margin-right: 0;
    }
  }
}

.week {
  display: contents;
  .day-item {
    text-align: left;
    width: 64rpx;
    margin-bottom: 20rpx;
    margin-right: 34rpx;
    &:last-child {
      margin-right: 0;
    }
  }
}

.day-item {
  cursor: pointer;
}

.not-current {
  color: #ccc;
}

.special-day {
  color: #fff;
}
.selected-day {
  text-decoration: underline;
}
.disabled {
  color: rgba(255, 255, 255, 0.5);
  pointer-events: none;
}
</style>
